#pragma once
#include <list>
#include <vector>
#include <map>
#include <string>
#include <iostream>
#include <stdint.h>
#include <memory>
#include <unordered_map>
#include <unordered_set>
#include "hdmap/HDMapExports.hpp"
#include "hdmap/Geometry.hpp"

/**
 * @brief Navinfo namespace
 *
 */
namespace Navinfo{
	/**
	* @brief Common namespace
	*
	*/
	namespace Common{
		enum ReturnCode{
			Code_Success = 0,
			Code_Fail,
			Code_None,
		};
	}

	namespace Engine{
		namespace DataSource{
			class NDSBaseObject;
			class NDSFixRoadAttribute;
			class NDSLink;
			class NDSLane;
			class NDSLaneGroupAssociation;
			class NDSLaneGroup;
			class NDSLaneBoundarySequential;
			class NDSLaneBoundary;
			class NDSLaneBoundaryGroup;
			class HDMapImpl;
		}
		class HDMapObjectTrafficLight;

		/**
		 *  @brief type of Road
		 */
		enum class HDMapLinkType : uint8_t
		{
			NO_SPECIAL = 0,				///< no special type
			RAMP = 1,					///< ramp road
			ROUNDABOUT = 2,				///< round road
			PARALLEL = 3,				///< parallel road
			SERVICE_ROAD = 4,			///< service road
			MAIN_ROAD = 5,				///< main road
			SQUARE = 6,					///< square road
			PEDESTRIAN_ZONE = 8,		///< pedestrian zone
			PEDESTRIAN = 9,				///< pedestrian road
			ROUNDABOUT_INTERIOR = 10,	///< inter road of round
			SLIP_ROAD = 11,				///< slip road
			SPECIAL_TRAFFIC_FIGURE = 12,///< special road flag
			BOUNDARY = 13				///< boundary of road
		};

		/**
		 *  @brief direction type
		 */
		enum class HDMapDirection : uint8_t
		{
			IN_NO_DIRECTION = 0,		///< direction unavailable
			IN_POSITIVE_DIRECTION = 1,	///< positive direction
			IN_NEGATIVE_DIRECTION = 2,	///< negative direction
			IN_BOTH_DIRECTIONS = 3		///< both direction
		};

		/**
		 *  @brief type iff vehicles. make it as a bit of mask
		 */
		enum HDMapVehicleTypes{
			VALIDFLAG = 0,			///< vehicle type valid flag
			PEDESTRIAN = 1,			///< people 
			BICYCLE = 2,			///< bike
			//AUTOCAR = 3,			///< (discard) auto dirve car 
			BUS = 4,				///< bus
			CARPOOL = 5,			///< restrictions on the number of people
			DELIVERY = 6,			///< business vehicle type
			MOTORCYCLE = 7,			///< motorcycle
			PERSONALCAR = 8,		///< personal car
			TAXI = 9,				///< taxi
			EMERGENCYVEHICLE =10,	///< emergency vehicle like ambulance
			TRUCK =11,				///< truck
		};



		/**
		 *  @brief Special type for speed limit query
		 */
		enum HDMapDependentType
		{
			SCHOOL = 0,
			SPEED_BUMP = 1,
			WEATHER_RAIN = 2,
			NO_DEPENDEDT_TYPE
		};

		enum HDMapDividerType
		{
			HAS_DIVIDER = 0,
			UNKNOWN_DIVIDER_TYPE = 1,
			LEGAL_DIVIDER = 2
		};

		enum HDMapDividerMode
		{
			LEFT_DIVIDER = 0,
			RIGHT_DIVIDER = 1
		};

		struct HDMapDivider
		{
			HDMapDividerType m_eDividerType;  //
			HDMapDividerMode m_eDividerMode;
			double dRangeStartPos;
			double dRangeEndPos;
		};
		

		/**
		 *  @brief Feature location reference info
		 */
		struct HDMapGeometryRangeReference{
			enum {
				RoadGeometry = 1,					///< reference from Road geometry
				LaneGeometry = 2,					///< reference from lane geometry
			} geometryReferenceType;				///< location reference from choice
			double dRangeStartPos = 0.0;			///< start postition (percentage) on geometry
			double dRangeEndPos = 0.0;				///< start postition (percentage) on geometry
		};

		/**
		 *  @brief superelevation average value
		 */
		enum SuperElevationType
		{
			SuperElevation_Flat = 0,							//Superelevation between 4 degrees towards curb and 4 degrees towards the middle of the road.
			SuperElevation_More_Than_4_Towards_Curb = 1,		//Superelevation more than 4 degrees and less or equal 6 degrees towards the curb.
			SuperElevation_More_Than_6_Towards_Curb = 2,		//Superelevation more than 6 degrees and less or equal 8 degrees towards the curb.
			SuperElevation_More_Than_8_Towards_Curb = 3,		//Superelevation more than 8 degrees towards curb.
			SuperElevation_More_Than_4_Towards_Middle = 4,		//Superelevation more than 4 degrees and less or equal 6 degrees towards the middle of the road.
			SuperElevation_More_Than_6_Towards_Middle = 5,		//Superelevation more than 4 degrees and less or equal 6 degrees towards the middle of the road.
			SuperElevation_More_Than_8_Towards_Middle = 6,		//Superelevation more than 8 degrees towards the middle of the road.

			SuperElevation_InValid = 9999999,
		};

		

		/**
		 *  @brief externs attribute of road geometry point 
		 */
		struct HDMapExtendAttribute{
			Navinfo::Engine::Math::Vec3d	mCoord;			///< Attribute position on geometry
			int32_t							mSlope;			///< slop value. unit: 0.0001 degree incline is positive, decline negative.
			int32_t							mCurvature;		///< curvate value. units: 0.000001/m
			SuperElevationType				mSuperElevation;
		};

		static const int32_t INVALID_SLOP_VALUE = 9999999;
		static const int32_t INVALID_CURVATURE_VALUE = 9999999;
		
		/**
		 *  @brief condition type of time 
		 */
		enum TimeDomainType : uint8_t
		{
			TIME_RANGE_OF_DAY = 1,		 //< time of day
			DATE_RANGE_OF_YEAR = 2,		 //< day of year
			DAYS_OF_WEEK = 3,			 //< day of week
		};

		/**
		 *  @brief define a date of year
		 */
		struct DayOfYear{
			bool operator <(const DayOfYear &rh)const{
				if (year < rh.year)
					return true;
				else if (year>rh.year)
					return false;
				else
				{
					if (month < rh.month)
						return true;
					else if (month>rh.month)
						return false;
					else
					{
						if (day < rh.day)
							return true;
						else if (day>rh.day)
							return false;
						else
							return false;
					}
				}
			}
			bool operator <=(const DayOfYear &rh)const{
				if (year < rh.year)
					return true;
				else if (year>rh.year)
					return false;
				else
				{
					if (month < rh.month)
						return true;
					else if (month>rh.month)
						return false;
					else
					{
						if (day < rh.day)
							return true;
						else if (day>rh.day)
							return false;
						else
							return true;
					}
				}
			}
			uint16_t year;
			uint8_t  month;
			uint8_t  day;
			bool     isInclusive;
		};

		/**
		 *  @brief defines a datetime reange
		 */
		struct DateRangeOfYear{
			bool IsInRange(const DayOfYear &day) const {
				if (isInclusive){
					if (startDay <= day && day <= endDay)
						return true;
				}
				return false;
			}
			DayOfYear startDay;		///< date range start
			DayOfYear endDay;		///< date range end
			bool isInclusive;
		};

		/**
		 * Defines a point of time in terms of hours and minutes.
		 */
		struct TimeOfDay
		{
			bool operator <(const TimeOfDay &rh) const {
				return (hour * 60 + minute) < (rh.hour * 60 + rh.minute);
			}
			bool operator ==(const TimeOfDay &rh) const {
				return hour == rh.hour && minute == rh.minute;
			}
			bool operator <=(const TimeOfDay &rh) const {
				return (hour * 60 + minute) <= (rh.hour * 60 + rh.minute);
			}
			uint8_t hour;    // 0 - 23
			uint8_t minute;  // 0 - 59
		};

		/**
		 * Specifies a period by start and end time.
		 */
		struct TimeRangeOfDay
		{
			TimeOfDay  startTime;			///< time range start
			TimeOfDay  endTime;				///< time range end
			bool       isInclusive;			///< flag indicate in the time range or not
		};

		/**
		 *  @brief Day if weak, as a bit of mask
		 */
		enum DayOfWeekBitPos{
			Monday = 1,						///< Monday
			Tuesday,						///< Tuesday
			Wednesday,						///< Wednesday
			Thursday,						///< Thursday
			Friday,							///< Friday
			Saturday,						///< Saturday
			Sunday,							///< Sunday
			Inclusive = 8,					///< if set means select else means unselect
		};

		/**
		 * Specifies for each day of a week
		 */
		typedef uint8_t DaysOfWeek;

		/**
		 *  @brief condition value of time
		 */
		union TimeDomain
		{
			TimeRangeOfDay          timeRangeOfDay;
			DateRangeOfYear			dateRangeOfYear;
			DaysOfWeek              daysOfWeek;
		};

		/**
		 *  @brief Validity Period
		 */
		struct TimePeriod{
			TimeDomainType timeType;
			TimeDomain timeDomain;
		};

		typedef uint16_t VehicleTypeSequence; ///< every bit means a vehicle type @see HDMapVehicleTypes

		class HDMapObjectInfo;
		class HDMapLaneInfo;
		class HDMapLaneBoundariesInfo;
		class HDMapLaneGroupInfo;
		/**
		 *  @brief information if road object
		 */

		enum HDMapRoadMedianShape{
			FLAT = 0,
			BERM = 1,
			DITCH = 2
		};

		enum HDMapRoadMedianSurface{
			PAVED = 0,
			UNPAVED = 1
		};

		enum HDMapRoadMedianDirection{
			LEFT_MEDIAN = 0,
			RIGHT_MEDIAN = 1
		};

		struct HDMapRoadMedian
		{
			double						m_nStartPos;
			double						m_nEndPos;

			uint16_t					m_nWidth;

			HDMapRoadMedianShape		m_shape;
			HDMapRoadMedianSurface		m_surface;
			HDMapRoadMedianDirection	m_Direction;
		};


		

		/**
		 *  @brief contivity type of lane
		 */
		enum class HDMapLaneConnectivityElementType : uint16_t
		{
			NORMAL_LANE = 0,			///< normal lane
			ENTRY_LANE = 1,				///< entry lane
			EXIT_LANE = 2,				///< exit lane
			EXIT_AND_ENTRY_LANE = 3,	///< exit and entry lane
			EXIT_OR_ENTRY_LANE = 4,		///< exit or entry lane
			TRAIN_TRACK = 5,			///< train track
			PUBLIC_TRANSPORT_STOP = 6,	///< transport stop public vehicle
			WAITING_AREA = 7			///< waiting area
		};

		/**
		 *  @brief type of lane boundary
		 */
		enum class HDMapLaneBoundaryType : uint16_t
		{
			NO_MARKING = 0,				///< no Making for the lane Boundary
			LONG_DASHED_LINE = 1,		///< the making is long dashed line
			DOUBLE_SOLID_LINE = 2,		///< the making is double solid line
			SINGLE_SOLID_LINE = 3,		///< the making is single solid line
			SOLID_LINE_DASHED_LINE = 4,	///< the making is solid line dashed line
			DASHED_LINE_SOLID_LINE = 5,	///< the making is dashed line solid line
			SHORT_DASHED_LINE = 6,		///< the making is short dashed line
			SHADED_AREA_MARKING = 7,	///< the making is shaded area marking
			DASHED_BLOCKS = 8,			///< the making is dashed blocks
			DOUBLE_DASHED_LINE = 9,		///< the making is double dashed line
			CROSSING_ALERT = 10,		///< the making is crossing alert
			CURB = 11,					///< the making is road curb
			WALL_FLAT = 12,				///< the making is flat wall
			WALL_TUNNEL = 13,			///< the making is tunnel wall
			BARRIER_JERSEY = 14,		///< the making is jersey barrier
			BARRIER_SOUND = 15,			///< the making is sound barrier
			BARRIER_CABLE = 16,			///< the making is cable barrier
			GUARDRAIL = 17,				///< the making is guardrail 
			FENCE = 18,					///< the making is fence
			CURB_TRAVERSABLE = 19,		///< the making is traversable curb 
			END_OF_ROAD = 20,			///< the making is end of road
			CLIFF = 21,					///< the making is cliff
			DITCH = 22,					///< the making is ditch
			GORE = 23,					///< the making is gore
			WALKING_AREA = 24,			///< the making is walking area
			OFFSET_SPACE = 25,			///< the making is offset space
			OTHER_BARRIER = 30,			///< the making is other barrier
			TYPE_UNKNOWN = 31			///< the making is unknown type
		};

		/**
		 *  @brief color of land marking
		 */
		enum HDMapColor{
			COLOR_WHITE = 0,			///< white
			COLOR_LIGHT_GRAY = 1,		///< light gray
			COLOR_GRAY = 2,				///< gray
			COLOR_DARK_GRAY = 3,		///< dark gray
			COLOR_BLACK = 4,			///< black
			COLOR_RED = 5,				///< red
			COLOR_YELLOW = 6,			///< yellow
			COLOR_GREEN = 7,			///< green
			COLOR_CYAN = 8,				///< cyan
			COLOR_BLUE = 9,				///< blue
			COLOR_ORANGE = 10,			///< orange
			Color_BROWN = 11,			///< brown
			COLOR_UNKNOWN = 15,			///< color unknown
		};
		typedef HDMapColor MarkingColor;
		typedef HDMapColor SignColor;

		/**
		 *  @brief material of lane boundary
		 */
		enum class HDMapLaneBoundaryMaterial : uint16_t
		{
			Material_MATERIAL_UNKNOWN = 0,			///< unknown material
			Material_METAL = 1,						///< metal
			Material_CONCRETE = 2,					///< concrete
			Material_STONE = 3,						///< stone
			Material_WOOD = 4,						///< wood
			Material_PLASTIC = 5,					///< plastic
			Material_TRANSPARENT = 6,				///< transparent
			Material_VIBRATION_MARKINGS = 7,			///< vibration markings
			Material_PAINTED_VIBRATION_DIVIDER = 8,	///< painted vibration divider
			Material_PAINTED = 9						///< painted
		};

		/**
		*  @brief class of lane marking
		*/
		enum class HDMapLaneMarkingDirection : uint16_t
		{
			OTHER = 0,							///< OTHER
			FORWARD = 1,						///< FORWARD 
			RIGHT = 2,							///< RIGHT
			RIGHTANDFORWARD = 3,				///< RIGHTANDFORWARD
			LEFT = 4,							///< LEFT
			LEFTANDFORWARD = 5,					///< LEFTANDFORWARD
			UTURN = 6,							///< UTURN
			FORWARDANDUTURN = 7,				///< FORWARDANDUTURN
			LEFTANDUTURN = 8,					///< LEFTANDUTURN 
			LEFTANDRIGHT = 9,					///< LEFTANDRIGHT
			LEFTCONFLUENCE = 10,				///< LEFTCONFLUENCE
			RIGHTCONFLUENCE = 11				///< RIGHTCONFLUENCE
		};

		enum class HDMapLaneType : uint16_t
		{
			REGUAR_LANE = 0,					///< normal lane
			EXPRESS_LANE =1,					///< fast speed lane
			SLOW_LANE = 2,						///< slow speed lane
			CARPOOL_LANE = 3,					///< carpool vehocle dedicated lane
			REGULATED_ACCESS_LANE = 4,			///< use for special purpose
			BICYCLE_LANE = 5,					///< bicycle lane
			BUS_LANE = 6,						///< bus lane
			TRAM_LANE = 7,						///< tram vehicle use lane
			PARKING_LANE = 8,					///< alow parking
			TRUCK_PARKING_LANE = 9,				///< alow truck parking
			SHOULDER_LANE = 10,					///< shoulder road 
			REVERSIBLE_LANE = 11,				///< reversible lane
			VARIABLE_DRIVING_LANE = 12							///< Variable driving lane
		};

		enum class HDMapLaneTransitionType : uint16_t
		{
			SPLIT = 0,							///< one Split more than one lane
			MERGE = 1,							///< lanes merge into one lane
			CONTINUE_LEFT = 2,					///< lane continue from left
			CONTINUE_RIGHT = 3,					///< lane continue from right
			START = 4,							///< lane start without connect
			END = 5,							///< lane end without connect
			OTHER = 6							///< other transition lane type
		};

		/**
		 *  @brief width value into for lane
		 */
		struct HDMapLaneWidthInfo{
			HDMapGeometryRangeReference	mRangeReference;				///< range info for the value
			uint32_t width;												///< width value
		};

		/**
		 *  @brief marking object from landmark, include virtual stop line and real stop line. 
		 *  real stop line has marking line on the ground and virtual stop line is not
		 */
		struct HDMapExtendStopLine{
			bool bObjectMarkingExist;									///< flag indicate stopline is vitual or real
			uint64_t nLaneId;											///< indicate this stop line is on the lane with id laneId
			uint64_t nObjectId;											///< real stop line id (when real_object_flag is true)
			HDMapGeometryRangeReference mRangeReference;				///< data info for position reference on geometry 

			std::map<uint64_t, std::weak_ptr<HDMapObjectInfo>> vtTrafficLightReference; ///< reference traffic light list
		};

		/**
		 *  @brief descript traffic light object and extended reference value
		 */
		struct HDMapExtendTrafficLight{
			std::weak_ptr<HDMapObjectInfo>								mTrafficLight;						///< traffic light object
			//std::map<uint64_t, std::weak_ptr<HDMapExtendStopLine>>
			std::vector<std::weak_ptr<HDMapExtendStopLine>>				realStopLineReferenceMap;			///< real stop line referenced
			std::vector<std::weak_ptr<HDMapExtendStopLine>>				virtualStopLineReferenceVec;		///< virtual stop line referenced
		};

		/**
		 *  @brief transition type info for lane
		 */
		struct HDMapLaneTransitionInfo{
			HDMapLaneTransitionType	laneTransitionType;					///< lane transition type
			HDMapGeometryRangeReference	mRangeReference;				///< reference range 
		};

		/**
		 *  @brief type of the location object
		 */
		enum HDMapObjectType
		{
			OBJECT_TYPE_SIGN = 1,				///< sign on road
			OBJECT_TYPE_POLE = 2,				///< pole on road
			OBJECT_TYPE_TRAFICLIGHT = 3,		///< trafic light
			OBJECT_TYPE_MARKING = 4,			///< marking on road such arrow
			OBJECT_TYPE_WALL = 5,				///< perpendicular wall on road, like wall on enterance of tunnel
			OBJECT_TYPE_OBSTACLE = 6,			///< traffic barrier on road
			OBJECT_TYPE_BARRIER = 7,			///< traffic barrier on road
			OBJECT_TYPE_OSF = 8,				///< Overhead Structure Face
			OBJECT_TYPE_Count,
		};
		
		/**
		 *  @brief height info unit: CM
		 */
		typedef uint16_t ObjectHeight;
		/**
		 *  @brief Upper Diameter Unit: cm
		 */
		typedef uint16_t UpperDiameter;
		/**
		 *  @brief Lower Diameter Unit: cm
		 */
		typedef uint16_t LowerDiameter;

		/**
		 *  @brief type of trafic sign
		 */
		enum TraficSignType{
			SIGN_TYPE_UNKNOWN = 0,
			SIGN_TYPE_SPEED_LIMIT,
			SIGN_TYPE_SPEED_LIMIT_END,
			SIGN_TYPE_ADVISORY_SPEED_LIMIT,
			SIGN_TYPE_ADVISORY_SPEED_LIMIT_END,
			SIGN_TYPE_NO_OVERTAKING,
			SIGN_TYPE_NO_OVERTAKING_END,
			SIGN_TYPE_DO_NOT_ENTER,
			SIGN_TYPE_ANIMALS,
			SIGN_TYPE_BICYCLE_PATH,
			SIGN_TYPE_VEHICLES_PROHIBITED,
			SIGN_TYPE_MOTORWAY_END,
			SIGN_TYPE_FALLING_ROCKS,
			SIGN_TYPE_HEIGHT_RESTRICTION,
			SIGN_TYPE_ICY_ROAD,
			SIGN_TYPE_LENGTH_RESTRICTION,
			SIGN_TYPE_MOTORWAY,
			SIGN_TYPE_NO_OVERTAKING_FOR_TRUCKS,
			SIGN_TYPE_NO_OVERTAKING_FOR_TRUCKS_END,
			SIGN_TYPE_PASSING_RESTRICTION,
			SIGN_TYPE_CARRIAGEWAY_NARROWS,
			SIGN_TYPE_SLIPPERY_ROAD,
			SIGN_TYPE_TRUCK_SPEED_LIMIT,
			SIGN_TYPE_TURN_RESTRICTION,
			SIGN_TYPE_WIDTH_RESTRICTION,
			SIGN_TYPE_WEIGHT_RESTRICTION,
			SIGN_TYPE_YIELD,
			SIGN_TYPE_CURVY_ROAD,
			SIGN_TYPE_NARROW_BRIDGE,
			SIGN_TYPE_TWO_WAY_TRAFFIC,
			SIGN_TYPE_PEDESTRIANS,
			SIGN_TYPE_CHILDREN,
			SIGN_TYPE_WIND,
			SIGN_TYPE_EMBANKMENT,
			SIGN_TYPE_VILLAGE_AHEAD,
			SIGN_TYPE_TUNNEL,
			SIGN_TYPE_FERRY_TERMINAL,
			SIGN_TYPE_HUMPBACK_BRIDGE,
			SIGN_TYPE_UNEVEN_ROAD,
			SIGN_TYPE_BUMP,
			SIGN_TYPE_DIP,
			SIGN_TYPE_ROAD_FLOODS,
			SIGN_TYPE_RAILROAD_CROSSING,
			SIGN_TYPE_HIGH_ACCIDENT_AREA,
			SIGN_TYPE_SLOW_DOWN,
			SIGN_TYPE_PASS_OBSTACLE,
			SIGN_TYPE_GENERAL_HAZARD,
			SIGN_TYPE_ROAD_WORKS,
			SIGN_TYPE_TRAFFIC_CONGESTION,
			SIGN_TYPE_PEDESTRIANS_PROHIBITED,
			SIGN_TYPE_HONKING_PROHIBITED,
			SIGN_TYPE_ONEWAY,
			SIGN_TYPE_PEDESTRIAN_PATH,
			SIGN_TYPE_END_OF_ALL_RESTRICTIONS,
			SIGN_TYPE_PRIORITY_ROAD,
			SIGN_TYPE_PRIORITY_OVER_ONCOMING,
			SIGN_TYPE_PEDESTRIAN_CROSSING,

			SIGN_TYPE_SHARP_CURVY_ROAD,
			SIGN_TYPE_LANE_END,
			SIGN_TYPE_ROLLOVER,
			SIGN_TYPE_TRAFIC_LIGHT_SIGNALS,
			SIGN_TYPE_STOP,
			SIGN_TYPE_NO_PARKING,
			SIGN_TYPE_INTERSECTION,
			SIGN_TYPE_REVERSE_CURVE,
			SIGN_TYPE_STEEP_HILLS,
			SIGN_TYPE_STEEP_DROP,
			SIGN_TYPE_WATCH_HANDICAPPED,
			SIGN_TYPE_LIGHT_UP_IN_TUNNEL,
			SIGN_TYPE_REVERSIBLE_LANE,
			SIGN_TYPE_MAINTAIN_SAFE_DISTANCE,
			SIGN_TYPE_SEPARATED_ROAD,
			SIGN_TYPE_CONFLUENCE,
			SIGN_TYPE_TRUCK_ESCAPE_RAMPS,
			SIGN_TYPE_ADVERSE_WEATHER,
			SIGN_TYPE_STOP_FOR_INSPECTION,
			SIGN_TYPE_CUSTOMS,
			SIGN_TYPE_LANE_DRIVING_DIRECTION,
			SIGN_TYPE_BUS_LANE,
			SIGN_TYPE_VEHICLE_LANE,
			SIGN_TYPE_NON_MOTOR_VEHICLE_LANE,
			SIGN_TYPE_BRT_Lane,
			SIGN_TYPE_HOV_Lane,
			SIGN_TYPE_PARKING,
			
			SIGN_TYPE_COUNT,
		};


		union TrafficSignContent
		{
			int16_t val_int;
		};

		/**
		 *  @brief shape of trafic sign
		 */
		enum TraficSignShape
		{
			SHAPE_TRIANGLE_TIP_UP = 0,					///< triangle tip up
			SHAPE_RECTANGLE = 1,						///< ectangle
			SHAPE_ROUND = 2,							///< round
			SHAPE_OCTAGON = 3,							///< octagon
			SHAPE_DIAMOND = 4,							///< diamond
			SHAPE_CROSBUCK = 5,							///< crosbuck
			SHAPE_TRIANGLE_TIP_DOWN = 6,				///< triangle tip down
			SHAPE_ELLIPSE = 7,							///< ellipse
			SHAPE_OTHER = 8,							///< other
			SHAPE_UNKNOWN = 15							///< unknown
		};
		/**
		 *  @brief type of pole object
		 */
		enum PoleObjectType{
			POLE_TYPE_GUARDRAIL_POST = 0,				///< guardrail post
			POLE_TYPE_LIGHT_POLE = 1,					///< light pole
			POLE_TYPE_DELINEATOR_POST = 2,				///< delineator post
			POLE_TYPE_REFLECTOR_POST = 3,				///< reflector post
			POLE_TYPE_GANTRY_POLE = 4,					///< gantry pole
			POLE_TYPE_SIGNPOST = 5,						///< signpost
			POLE_TYPE_OTHER = 6,						///< other
			POLE_TYPE_UNCLASSIFIED = 7,					///< unclassified
			POLE_TYPE_UNKNOWN							///< unknown
		};
		/**
		 *  @brief type of marking object
		 */
		enum MarkingType{

			Marking_Type_TEXT = 0,						///< Text written on the road surface. The text itself is not specified.
			Marking_Type_ARROW_STRAIGHT = 1,			///< One straight arrow in driving direction.
			Marking_Type_ARROW_LEFT = 2,				///< One arrow pointing left (within driving direction).
			Marking_Type_ARROW_RIGHT = 3,				///< One arrow pointing right (within driving direction).
			Marking_Type_ARROW_STRAIGHT_AND_LEFT = 4,	///< One combined arrow where one part points straight in driving direction and the other part to the left.
			Marking_Type_ARROW_STRAIGHT_AND_RIGHT = 5,	///< One combined arrow where one part points straight in driving direction and the other part to the right.
			Marking_Type_ARROW_LEFT_AND_RIGHT = 6,		///< One combined arrow where one part points to the left (within driving direction) and the other part to the right.
			Marking_Type_LINE_ELEMENT = 7,				///< A rectangular element of a line, for example a dot or block.
			Marking_Type_STOP_LINE = 8,					///< A line (mainly) perpendicular to the the driving direction indicating where to stop.
			Marking_Type_CROSSWALK = 9,					///< A combination of lines that make up a crosswalk.
			Marking_Type_SIGN = 10,						///< A sign painted on the road surface. The sign type itself is not specified.
			Marking_Type_DASHED_LINE_ELEMENT = 11,		///< A single element of a dashed line.
			Marking_Type_YIELD_INDICATION = 12,			///< Line of triangles painted on the surface to indicated yield. 
			Marking_Type_VISUAL_SPEED_BUMP = 13,		///< Speed bump decorated with paint.
			Marking_Type_SHADED_AREA = 14,				///< Shaded area.
			Marking_Type_OTHER = 15,					///< unknown
		};
		/**
		 *  @brief Geometry indicater of marking object
		 */
		enum MarkingGeometryType
		{
			GEOMETRY_UNKNOWN = 0,						///< geometry type unknow
			GEOMETRY_BOUNDARY_BOX = 1,					///< geometry for boundarybox
			GEOMETRY_CENTER_LINE = 2,					///< geometry for center line
		};
		
		/**
		 *  @brief control type of traffic light
		 */
		enum TrafficLightType
		{
			TrafficLight_Type_UNKNOWN = 0,				///< Not applicable
			TrafficLight_Type_INTERSECTION = 1,			///< Intersection traffic flow control Signal
			TrafficLight_Type_RAMP_CONTROL = 2,			///< Ramp Control Signal
			TrafficLight_Type_TOLL_GATE = 3,				///< Toll Gate Signal
			TrafficLight_Type_LANE_STATUS = 4,			///< Lane Status Signal
			TrafficLight_Type_TIMER = 5,					///< Timer
		};

		/**
		 *  @brief orientation type of traffic light
		 */
		enum TrafficLightOrientation
		{
			TrafficLight_Orientation_UNKNOWN = 0,
			TrafficLight_Orientation_VERTICAL = 1,
			TrafficLight_Orientation_HORIZONTAL = 2,
		};
	}
}

namespace Navinfo{
	namespace Common{

		typedef Navinfo::Engine::HDMapObjectType ENObjectType;
		
		enum ENReferenceType{
			ENReferenceType_None,
			ENReferenceType_MultiDigitized,
		};
	}
}


